#include "Protocol.hpp"
#include "Sock.hpp"
#include <ctime>
#include <unistd.h>

static void Usage(const std::string& proc)
{
    std::cout << "\nUsage: " << proc << " ServerIP ServerPort" << std::endl;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    std::string ServerIP = argv[1];
    uint16_t ServerPort = atoi(argv[2]);
    Sock sock;
    int sockfd = sock.Socket();
    if(!sock.Connet(sockfd, ServerIP, ServerPort))
    {
        std::cerr << "Connet Error!" << std::endl;
        exit(2);
    }

    bool quit = false;
    std::string buffer;
    srand((unsigned int)time(nullptr));
    const char* op = "+-*/%";

    while(!quit)
    {
        // 获取需求
        Request req;
        req._x = rand() % 100;
        req._y = rand() % 100;
        req._op = op[rand() % 5];

        // 序列化
        std::string str = req.Serialize();
        std::string tmp = str;
        // 添加报头
        str = Encode(str);
        // 向服务器发起请求
        Send(sockfd, str);
        // 接收服务器的应答
        while(true)
        {
            bool ret = Recv(sockfd, &buffer);
            // 服务器关闭连接或Recv异常
            if(!ret)
            {
                quit = true;
                break;
            }

            std::string package = Decode(buffer);
            if(package.empty()) continue;
            // 接收到一个完整的报文
            Response resp;
            resp.Deserialize(package);
            std::string err;
            switch(resp._code)
            {
            case 1:
                err = "除0错误";
                break;
            case 2:
                err = "模0错误";
                break;
            case 3:
                err = "非法操作";
                break;
            default:
                // std::cout << "[Calculate Success] " << tmp <<  " = " << resp._ret << std::endl;
                // std::cout << "[Calculate Success] " << resp._ret << std::endl;
                std::cout << "[Calculate Success] " << resp._x << " " << resp._op << " " << resp._y << " = " << resp._ret << std::endl;
                break;
            }
            if(!err.empty()) std::cerr << err << std::endl;
            sleep(1);
            break;
        }
    }
    close(sockfd);

    return 0;
}